Николай Ланец
25 янв. 2021 г., 17:07

Поиск в документе всех элементов с position: absolute | fixed

Всем привет!

Сегодня Саша Марков справедливо заметил, что использовать более высокоуровневые технологии удобней и продуктивней, чем низкоуровневые. Такую точку зрения поддерживают многие. Я с точки зрения удобства и эффективности не буду спорить, но ИМХО останется прежним - всегда надо стремиться к более низкоуровневым технологиям, чтобы понимать что и как можно делать на более высоком уровне. Тем более, что высокоуровневые технологии не всегда дают в полной мере все то же самое, что доступно на низком уровне. И сейчас я покажу это на примере, буквально вот сейчас родившемся, хотя каждый день по куче таких рождается.

В общем, задача состояла в следующем: на странице найти все HTML-элементы, у которых стиль position не static и не relative (на самом деле меня интересовали все с position: absolute и position: fixed, но вдруг еще что необычное есть?).

Вот такой вот результат получился в devTools браузера.

Правда наглядно получилось?

А если развернуть полученный массив, то можно мышкой наводить на элементы и в браузере сразу будут подсвечиваться они.


Так вот, делается все это всего одной строкой, прям в консоли браузера:
console.table([...document.querySelectorAll('*')].filter(n => ["static", "relative"].indexOf(n.computedStyleMap().get('position').value) === -1 ).map(n => [ n.computedStyleMap().get('position').value, n]))
Это чистый JS, не требующий никакой дополнительной библиотеки. Давайте его разберем по кусочкам.

console.table() - один из методов объекта console, который выводит не просто текстовые сообщения в лог, а формирует для их отображения таблицы. Документация: https://developer.mozilla.org/ru/docs/Web/API/Console/table

Нам этот метод понадобился для вывода найденных элементов.

document.querySelectorAll('*') - поиск всех дочерних элементов на всех уровнях по заданному селектору (для тех, что юзал jQuery, этот метод, как и querySelector наверняка вызовет дежавю). Документация: https://developer.mozilla.org/ru/docs/Web/API/Document/querySelectorAll

В нашем случае мы его использовали просто для поиска вообще всех элементов в документе.

.filter(n => ["static", "relative"].indexOf(n.computedStyleMap().get('position').value) === -1 ) Эту сложносоставную конструкцию следует рассматривать в целом, и воспринимать примерно так: Фильтровать полученный массив элементов, вернуть новый массив, который будет содержать только элементы, отвечающие условию "стиль position не должен быть ни static, ни relative".

Документация:

Кстати, самое интересное здесь - computedStyleMap(). Собирает все стили, как определенные в CSS, так и инлайновые, то есть заданные элементу через атрибут style="...".

Отдельно обратите внимание на конструкцию [...document.querySelectorAll('*')].
Дело в том, что querySelectorAll возвращает объект NodeList, который не является массивом, и чтобы перебрать все элементы, надо юзать дополнительные методы типа for. Мне в таком случае удобней заюзать так называемую Spread notation (более распространенный термин - деградация), чтобы из этого итерируемого объекта получить новый массив, который будет именно Array, и с которым я уже смогу фильтровать, перечислять и т.п. в привычном стиле.

.map() - перечисление элементов массива и формирование на выходе нового массива с этими же или измененными данными.


В общем, к чему я все это? А к тому, что старайтесь изучать больше низкий уровень, и только потом более высокий (для более быстрой работы). Высокоуровневые технологии постоянно меняются. Вот когда-то jQuery была в новинку, потом она заполонила весь веб, и казалось, без нее никуда, а сейчас мы наблюдаем ее закат. Было не мало других библиотек, которые многие из вас, возможно, даже не слышали (типа MooTools, Prototype и т.п.), которые появились еще до Жучки и уже канули в лету (куда и Жучка скорее всего тоже отправится). А вот JS как был, так и есть. Конечно он изменился, он не остался ровно таким, как был, но все же на низком уровне изменения не так быстро появляются, как в более высокоуровневых решениях. И вот если вы ориентируетесь в низкоуровневых решениях, то вы с легкостью выберете себе новый современный высокоуровневый инструмент, а не будете умирать как специалист вместе с устаревшей технологией.

Добавить комментарий